﻿using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Forms;
using static 摸鱼._数据库._方案._步骤;
using static 摸鱼.全局类;
using Button = System.Windows.Forms.Button;
using Control = System.Windows.Forms.Control;
using FontStyle = System.Drawing.FontStyle;
using Label = System.Windows.Forms.Label;
using Point = System.Drawing.Point;
using Size = System.Drawing.Size;
using TextBox = System.Windows.Forms.TextBox;

namespace 摸鱼
{
    internal static class 截屏扩展
    {
        public static void 显示(this 截屏? 截屏窗体)
        {
            var thread = new Thread(() =>
            {
                截屏.实例 = new 截屏();
                var 实例 = 截屏.实例;

                // 设置窗体属性
                实例.FormBorderStyle = FormBorderStyle.None;
                实例.WindowState = FormWindowState.Maximized;
                实例.TopMost = true;
                实例.BackgroundImage = 截屏.全屏截图;

                // 设置窗体为工具窗口，不在任务栏显示
                SetWindowLong(实例.Handle, GWL_EXSTYLE,
                    GetWindowLong(实例.Handle, GWL_EXSTYLE) | WS_EX_TOOLWINDOW);

                MainWindow.任务s.Enqueue(() =>
                {
                    Style contextMenuStyle = (Style)App.Current.TryFindResource(typeof(ContextMenu));
                    截屏.右键菜单 = (ContextMenu)MainWindow.This.FindResource("截屏右键菜单");
                    截屏.右键菜单.Style = contextMenuStyle;
                    截屏.右键菜单.StaysOpen = true;
                });

                // 初始化放大镜
                截屏.初始化放大镜();
                System.Windows.Forms.Application.Run(实例);
            });

            thread.SetApartmentState(ApartmentState.STA);
            thread.IsBackground = true;
            thread.Start();
        }

        [DllImport("user32.dll", SetLastError = true)]
        private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int GetWindowLong(IntPtr hwnd, int nIndex);
        private const int WS_EX_TOOLWINDOW = 0x80;
        private const int GWL_EXSTYLE = -20;
    }

    public partial class 截屏 : Form
    {
        public static bool 测试BUG模式 = false;
        public static 截屏 实例;
        public static ContextMenu 右键菜单;

        // 截图相关
        private Bitmap 全屏截图缓存;
        private Graphics 截图Graphics;
        private 框选工具 框选器;

        // 坐标信息相关字段
        private string 坐标信息文本 = "坐标: 0, 0";
        private Point 坐标信息位置 = Point.Empty;
        private bool 显示坐标信息 = false;

        // 放大镜相关
        private static 放大镜 放大镜实例;
        private static int 放大镜尺寸 = 200; // 放大镜窗口尺寸
        private static int 放大区域尺寸 = 20; // 实际放大的区域尺寸

        public 截屏()
        {
            实例 = this;
            InitializeComponent();
            InitializeCapture();
        }

        private void InitializeComponent()
        {
            this.SuspendLayout();

            // 设置窗体样式
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer |
                         ControlStyles.UserPaint |
                         ControlStyles.AllPaintingInWmPaint, true);
            this.DoubleBuffered = true;
            this.BackColor = Color.White;

            // 事件绑定
            this.MouseDown += 截屏_MouseDown;
            this.MouseUp += 截屏_MouseUp;
            this.MouseMove += 截屏_MouseMove;
            this.Paint += 截屏_Paint;
            this.KeyDown += 截屏_KeyDown;

            this.ResumeLayout(false);
        }
        private void 更新坐标信息(Point 鼠标位置)
        {
            // 更新文本内容
            坐标信息文本 = $"坐标: {鼠标位置.X}, {鼠标位置.Y}";
            if (框选器.框选中)
            {
                坐标信息文本 += $" | 选区: {框选器.宽度} × {框选器.高度}";
            }

            // 计算坐标信息位置（固定在放大镜下方）
            坐标信息位置 = 计算坐标信息位置(鼠标位置);
            显示坐标信息 = true;

            // 触发重绘
            this.Invalidate();
        }
        private Point 计算坐标信息位置(Point 鼠标位置)
        {
            if (放大镜实例 == null || 放大镜实例.IsDisposed || !放大镜实例.Visible)
            {
                // 如果没有放大镜，使用原来的计算方式
                return 计算备用位置(鼠标位置);
            }

            // 固定在放大镜下方
            var 放大镜位置 = 放大镜实例.Location;
            var 放大镜宽度 = 放大镜实例.Width;

            // 计算文字尺寸
            var 字体 = new Font("Arial", 12, FontStyle.Bold);
            var 文字尺寸 = this.CreateGraphics().MeasureString(坐标信息文本, 字体);

            // 坐标信息位置在放大镜正下方，宽度与放大镜相同
            int x = 放大镜位置.X;
            int y = 放大镜位置.Y + 放大镜实例.Height - 30; // 在放大镜内部下方显示

            // 确保在屏幕范围内
            x = Math.Max(0, Math.Min(x, 屏幕宽度 - 放大镜宽度));
            y = Math.Max(0, Math.Min(y, 屏幕高度 - 30));

            return new Point(x, y);
        }
        // 备用位置计算（当没有放大镜时使用）
        private Point 计算备用位置(Point 鼠标位置)
        {
            var 字体 = new Font("Arial", 12, FontStyle.Bold);
            var 文字尺寸 = this.CreateGraphics().MeasureString(坐标信息文本, 字体);
            var 标签尺寸 = new Size((int)文字尺寸.Width + 8, (int)文字尺寸.Height + 2);

            // 简单的右下角位置
            int x = 鼠标位置.X + 25;
            int y = 鼠标位置.Y + 25;

            // 调整位置确保在屏幕内
            if (x + 标签尺寸.Width > 屏幕宽度)
                x = 屏幕宽度 - 标签尺寸.Width - 10;
            if (y + 标签尺寸.Height > 屏幕高度)
                y = 屏幕高度 - 标签尺寸.Height - 10;

            return new Point(x, y);
        }
        private void InitializeCapture()
        {
            // 创建全屏截图
            全屏截图缓存 = new Bitmap(屏幕宽度, 屏幕高度, PixelFormat.Format32bppArgb);
            截图Graphics = Graphics.FromImage(全屏截图缓存);
            截图Graphics.CopyFromScreen(0, 0, 0, 0, new Size(屏幕宽度, 屏幕高度));

            // 初始化框选工具
            框选器 = new 框选工具();

            this.BackgroundImage = 全屏截图缓存;
        }

        public static void 初始化放大镜()
        {
            放大镜实例 = new 放大镜(放大镜尺寸, 放大区域尺寸);
            // 确保放大镜在截屏窗体之上但在鼠标之下
            if (实例 != null && 放大镜实例 != null)
            {
                放大镜实例.Owner = 实例;
            }
        }

        // 鼠标事件处理
        private void 截屏_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                关闭截屏();
            }
            else if (e.Button == MouseButtons.Left)
            {
                框选器.开始框选(e.Location);
                this.Invalidate(); // 触发重绘
            }
        }

        private void 截屏_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && 框选器.框选中)
            {
                框选器.结束框选();
                Console.WriteLine("鼠标左键已抬起");

                // 显示右键菜单
                MainWindow.任务s.Enqueue(() =>
                {
                    foreach (MenuItem item in 右键菜单.Items)
                        item.Click += 菜单项_Click;
                    右键菜单.Placement = PlacementMode.Mouse;
                    右键菜单.IsOpen = true;
                });
            }
        }
        private void 截屏_MouseMove(object sender, MouseEventArgs e)
        {
            // 更新鼠标位置
            var 鼠标位置 = e.Location;

            // 更新框选
            if (框选器.框选中)
            {
                框选器.更新框选(鼠标位置);
            }

            // 更新放大镜
            更新放大镜(鼠标位置);

            // 更新坐标信息显示
            更新坐标信息(鼠标位置);

            // 触发重绘（同时绘制框选和坐标信息）
            this.Invalidate();
        }

        private void 截屏_Paint(object sender, PaintEventArgs e)
        {
            var g = e.Graphics;

            // 绘制框选区域
            if (框选器.框选中)
            {
                框选器.绘制(g);
            }

            // 绘制坐标信息
            if (显示坐标信息)
            {
                绘制坐标信息(g);
            }
        }
        private void 绘制坐标信息(Graphics g)
        {
            if (放大镜实例 == null || 放大镜实例.IsDisposed || !放大镜实例.Visible)
            {
                // 没有放大镜时使用原来的绘制方式
                绘制独立坐标信息(g);
                return;
            }

            var 字体 = new Font("Arial", 12, FontStyle.Bold);
            var 文字尺寸 = g.MeasureString(坐标信息文本, 字体);
            var 放大镜宽度 = 放大镜实例.Width;

            // 计算坐标信息区域（与放大镜同宽）
            var 坐标区域 = new RectangleF(
                坐标信息位置.X,
                坐标信息位置.Y,
                放大镜宽度,
                文字尺寸.Height + 8
            );

            // 绘制黑色背景（与放大镜对齐）
            g.FillRectangle(Brushes.Black, 坐标区域);

            // 绘制白色文字（居中显示）
            var 文字位置 = new PointF(
                坐标区域.X + (放大镜宽度 - 文字尺寸.Width) / 2,
                坐标区域.Y + 4
            );

            g.DrawString(坐标信息文本, 字体, Brushes.White, 文字位置);
        }
        // 独立坐标信息绘制（当没有放大镜时）
        private void 绘制独立坐标信息(Graphics g)
        {
            var 字体 = new Font("Arial", 12, FontStyle.Bold);
            var 文字尺寸 = g.MeasureString(坐标信息文本, 字体);

            // 计算文字矩形区域
            var 文字矩形 = new RectangleF(
                坐标信息位置.X,
                坐标信息位置.Y,
                文字尺寸.Width + 8,
                文字尺寸.Height + 2
            );

            // 绘制黑色背景
            g.FillRectangle(Brushes.Black,
                文字矩形.X - 2, 文字矩形.Y - 2,
                文字矩形.Width + 4, 文字矩形.Height + 4);

            // 绘制白色文字
            g.DrawString(坐标信息文本, 字体, Brushes.White,
                文字矩形.X + 2, 文字矩形.Y + 2);
        }
        private void 截屏_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                关闭截屏();
            }
        }

        // 放大镜功能
        private void 更新放大镜(Point 鼠标位置)
        {
            if (放大镜实例 != null && !放大镜实例.IsDisposed)
            {
                放大镜实例.更新位置(鼠标位置, 全屏截图缓存);
            }
        }

        // 截图获取
        public static Bitmap 全屏截图
        {
            get
            {
                var 截图 = new Bitmap(屏幕宽度, 屏幕高度, PixelFormat.Format32bppArgb);
                using (var g = Graphics.FromImage(截图))
                {
                    g.CopyFromScreen(0, 0, 0, 0, new Size(屏幕宽度, 屏幕高度));
                }
                return 截图;
            }
        }

        private Bitmap 获取框选截图()
        {
            var 区域 = 框选器.框选区域;
            var 截图 = new Bitmap(区域.Width, 区域.Height, PixelFormat.Format32bppArgb);

            using (var g = Graphics.FromImage(截图))
            {
                g.DrawImage(全屏截图缓存, new Rectangle(0, 0, 区域.Width, 区域.Height),
                          区域, GraphicsUnit.Pixel);
            }

            return 截图;
        }

        // 菜单处理
        private async void 菜单项_Click(object o, RoutedEventArgs e)
        {
            MainWindow.This.数据输入框.TextChanged -= MainWindow.This.数据输入框_TextChanged;
            System.Windows.Input.Keyboard.Focus(MainWindow.This.数据输入框);
            Console.WriteLine($"测试模式={测试BUG模式}");
            // 测试BUG模式：立即关闭
            if (测试BUG模式)
            {
                立即关闭();
                await MoyuThreadPool.Delay(10);
            }

            try
            {
                var 菜单项 = (MenuItem)o;
                switch ((string)菜单项.Header)
                {
                    case "获取区域":
                        var 区域 = 框选器.框选区域;
                        MainWindow.This.数据输入框.替换文本($"{区域.X},{区域.Y},{区域.Right},{区域.Bottom}");
                        break;

                    case "获取框选面积":
                        int 面积 = 框选器.宽度 * 框选器.高度;
                        MainWindow.This.数据输入框.替换文本($"{面积},{面积}");
                        break;

                    case "获取色块面积":
                        await 处理色块面积获取();
                        break;

                    case "获取截图":
                        Console.WriteLine("获取截图第一步");
                        var 截图1 = 获取框选截图();
                        if (截图1 != null)
                        {
                            Console.WriteLine("已保存截图");
                            MainWindow.This.数据输入框.添加图片(new(截图1));
                        }
                        else
                            Console.WriteLine("截图=null");
                        break;

                    case "获取区域和截图":
                        var 区域2 = 框选器.框选区域;
                        MainWindow.This.数据输入框.替换文本($"{区域2.X},{区域2.Y},{区域2.Right},{区域2.Bottom}");
                        MainWindow.This.强制改变数据 = true;

                        MainWindow.This.数据输入框任务s.Enqueue(() =>
                            MainWindow.任务s.Enqueue(MainWindow.This.数据输入框改变));

                        await MoyuThreadPool.Delay(10);

                        var 截图2 = 获取框选截图();
                        if (截图2 != null)
                        {
                            MainWindow.This.数据输入框.添加图片(new(截图2));
                        }
                        break;
                }

                MainWindow.This.强制改变数据 = true;
                MainWindow.This.数据输入框_TextChanged(null, null);
                MainWindow.This.数据输入框.TextChanged += MainWindow.This.数据输入框_TextChanged;
            }
            catch (Exception ex)
            {
                if (!测试BUG模式)
                {
                    关闭截屏();
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine($"菜单处理异常: {ex.Message}");
                }
            }

            if (!测试BUG模式)
            {
                关闭截屏();
            }
        }

        private async System.Threading.Tasks.Task 处理色块面积获取()
        {
            using (var inputForm = new 输入对话框("请输入精准度（0.0-1.0）:", "0.95"))
            {
                inputForm.TopMost = true;

                if (inputForm.ShowDialog() == DialogResult.OK)
                {
                    if (double.TryParse(inputForm.答案, out double 精准度))
                    {
                        精准度 = Math.Clamp(精准度, 0.0, 1.0);

                        // 使用OpenCV处理色块面积计算
                        using (var mat = 全屏截图缓存.ToMat())
                        using (var 区域mat = new Mat(mat, new OpenCvSharp.Rect(
                            框选器.框选区域.X, 框选器.框选区域.Y,
                            框选器.框选区域.Width, 框选器.框选区域.Height)))
                        {
                            int 色块面积 = await 计算色块面积(区域mat, 精准度);
                            MainWindow.This.数据输入框.替换文本($"{色块面积},{色块面积}");
                        }
                    }
                    else
                    {
                        System.Windows.Forms.MessageBox.Show("请输入有效的数字！");
                    }
                }
            }
        }

        private async System.Threading.Tasks.Task<int> 计算色块面积(Mat 区域图像, double 精准度)
        {
            return await System.Threading.Tasks.Task.Run(() =>
            {
                try
                {
                    using (var hsv = new Mat())
                    {
                        Cv2.CvtColor(区域图像, hsv, ColorConversionCodes.BGR2HSV);

                        // 获取中心点颜色作为基准
                        var 中心点 = new Point(区域图像.Width / 2, 区域图像.Height / 2);
                        var 基准颜色 = hsv.At<Vec3b>(中心点.Y, 中心点.X);

                        // 计算容差
                        int h容差 = (int)((1 - 精准度) * 30);
                        int s容差 = (int)((1 - 精准度) * 100);
                        int v容差 = (int)((1 - 精准度) * 100);

                        // 创建颜色范围
                        var 下限 = new Scalar(
                            Math.Max(0, 基准颜色.Item0 - h容差),
                            Math.Max(0, 基准颜色.Item1 - s容差),
                            Math.Max(0, 基准颜色.Item2 - v容差));

                        var 上限 = new Scalar(
                            Math.Min(180, 基准颜色.Item0 + h容差),
                            Math.Min(255, 基准颜色.Item1 + s容差),
                            Math.Min(255, 基准颜色.Item2 + v容差));

                        // 创建掩码
                        using (var 掩码 = new Mat())
                        {
                            Cv2.InRange(hsv, 下限, 上限, 掩码);
                            return Cv2.CountNonZero(掩码);
                        }
                    }
                }
                catch
                {
                    return 0;
                }
            });
        }

        // 关闭处理
        private void 关闭截屏()
        {
            if (测试BUG模式)
            {
                立即关闭();
                return;
            }

            // 正常关闭流程
            隐藏界面元素();

            // 隐藏坐标信息（不需要特殊处理，因为窗体关闭时会自动清理）
            显示坐标信息 = false;

            if (放大镜实例 != null && !放大镜实例.IsDisposed)
            {
                放大镜实例.BeginInvoke(new Action(() =>
                {
                    放大镜实例.Close();
                    放大镜实例.Dispose();
                }));
            }

            if (实例 != null && !实例.IsDisposed)
            {
                实例.BeginInvoke(new Action(() =>
                {
                    实例.Close();
                    实例.Dispose();
                    实例 = null;
                    System.Windows.Forms.Application.ExitThread();
                }));
            }
        }

        private void 立即关闭()
        {
            try
            {
                隐藏界面元素();

                if (放大镜实例 != null)
                {
                    try { 放大镜实例.Close(); } catch { }
                    try { 放大镜实例.Dispose(); } catch { }
                }

                if (实例 != null && !实例.IsDisposed)
                {
                    实例.BeginInvoke(new Action(() =>
                    {
                        实例.Close();
                        实例.Dispose();
                        实例 = null;
                        System.Windows.Forms.Application.ExitThread();
                    }));
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"立即关闭异常: {ex.Message}");
            }
        }

        private void 隐藏界面元素()
        {
            MainWindow.任务s.Enqueue(() =>
            {
                try
                {
                    if (右键菜单 != null)
                    {
                        右键菜单.IsOpen = false;
                        foreach (MenuItem item in 右键菜单.Items)
                            item.Click -= 菜单项_Click;
                    }
                }
                catch { }
            });
        }

        // 调试功能
        public static void 设置测试模式(bool 启用)
        {
            测试BUG模式 = 启用;
            System.Diagnostics.Debug.WriteLine($"截屏测试模式: {(启用 ? "已启用" : "已禁用")}");
        }



        public static void 初始化()
        {
            图片 = new();
        }

        //图片管理
        public static 图片管理 图片;
        public static double SaveTime;
        public class 图片管理
        {
            private DXGIFastCapture 桌面复制;
            public 图片管理()
            {
                桌面复制 = new DXGIFastCapture(MainWindow.This, 0);
            }
            public OpenCvSharp.Mat this[int index, imageType._mat type]
            {
                get
                {
                    var frame = 桌面复制.CaptureFrame();
                    frame = 处理屏蔽区域(frame);
                    for (int i = 0; i < index; i++)
                        frame.PyrDown();
                    return frame;
                }
            }
            public Bitmap this[int index, imageType._bitmap type]
            {
                get
                {
                    var frame = 桌面复制.CaptureFrame();
                    frame = 处理屏蔽区域(frame);
                    for (int i = 0; i < index; i++)
                        frame.PyrDown();
                    try
                    {
                        return frame.ToBitmap();
                    }
                    finally
                    {
                        frame.Dispose();
                    }
                }
            }
        }
        private static Mat 处理屏蔽区域(Mat 新帧z)
        {
            Dictionary<DateTime, _屏蔽区域> 新数据 = new();
            foreach (var item in 屏蔽区域)
            {
                if ((DateTime.Now - item.Key).TotalMilliseconds > item.Value.屏蔽时长)
                    continue;
                else
                {
                    新数据.Add(item.Key, item.Value);
                    System.Drawing.Rectangle 区域 = item.Value.区域;
                    Cv2.Rectangle(新帧z, new OpenCvSharp.Rect(区域.X, 区域.Y, 区域.Width, 区域.Height), new Scalar(0, 0, 0), -1);
                }
            }
            屏蔽区域 = new(新数据);
            return 新帧z;
        }

        //取色管理
        public static 颜色 取色(int x, int y)
        {
            return 处理屏蔽区域(图片[0, imageType.Mat]).GetPixel(x, y);
        }
    }

    // 框选工具类
    public class 框选工具
    {
        public bool 框选中 { get; private set; } = false;
        // 计算实际的框选区域（支持所有方向）
        public Rectangle 框选区域
        {
            get
            {
                int x = Math.Min(起点.X, 终点.X);
                int y = Math.Min(起点.Y, 终点.Y);
                int width = Math.Abs(终点.X - 起点.X);
                int height = Math.Abs(终点.Y - 起点.Y);
                return new Rectangle(x, y, width, height);
            }
        }

        public int 宽度 => Math.Abs(终点.X - 起点.X);
        public int 高度 => Math.Abs(终点.Y - 起点.Y);

        private Point 起点;
        private Point 终点;

        public void 开始框选(Point 位置)
        {
            起点 = 位置;
            终点 = 位置 + new Size(1, 1);
            框选中 = true;
            Console.WriteLine(nameof(开始框选));
        }

        public void 更新框选(Point 新位置)
        {
            终点 = 新位置;
        }

        public void 结束框选()
        {
            框选中 = false;
        }

        public void 绘制(Graphics g)
        {
            if (!框选中) return;

            var 区域 = 框选区域;

            // 绘制半透明填充
            using (var 画刷 = new SolidBrush(Color.FromArgb(30, 0, 120, 215)))
            {
                g.FillRectangle(画刷, 区域);
            }

            // 绘制边框
            using (var 画笔 = new Pen(Color.FromArgb(255, 0, 120, 215), 2))
            {
                g.DrawRectangle(画笔, 区域);
            }

            // 绘制尺寸信息
            var 信息 = $"{宽度} × {高度}";
            var 字体 = new Font("Arial", 12, FontStyle.Bold);
            var 文字尺寸 = g.MeasureString(信息, 字体);

            // 计算文字位置（避免超出屏幕）
            var 文字位置 = new PointF(区域.X + 5, 区域.Y - 文字尺寸.Height - 5);
            if (文字位置.Y < 0) 文字位置.Y = 区域.Y + 5; // 如果上方空间不够，显示在内部

            // 文字背景
            g.FillRectangle(Brushes.Black,
               文字位置.X - 2, 文字位置.Y - 2,
               文字尺寸.Width + 4, 文字尺寸.Height + 4);

            g.DrawString(信息, 字体, Brushes.White, 文字位置);

            // 绘制四个角的控制点（可选，提供更好的视觉反馈）
            绘制控制点(g, 区域);
        }

        private void 绘制控制点(Graphics g, Rectangle 区域)
        {
            int 点大小 = 6;
            using (var 画刷 = new SolidBrush(Color.White))
            using (var 画笔 = new Pen(Color.Black, 1))
            {
                // 四个角
                Point[] 角点 =
                {
                new Point(区域.Left, 区域.Top),           // 左上
                new Point(区域.Right, 区域.Top),          // 右上  
                new Point(区域.Left, 区域.Bottom),        // 左下
                new Point(区域.Right, 区域.Bottom)        // 右下
            };

                foreach (var 点 in 角点)
                {
                    var 矩形 = new Rectangle(点.X - 点大小 / 2, 点.Y - 点大小 / 2, 点大小, 点大小);
                    g.FillRectangle(画刷, 矩形);
                    g.DrawRectangle(画笔, 矩形);
                }
            }
        }
    }

    public class 放大镜 : Form
    {
        private PictureBox 放大画面;
        private int 放大倍数;
        private int 采样尺寸;
        // 坐标信息相关
        private int 坐标信息高度 = 30; // 坐标信息区域高度
        // 提供位置信息给主窗体访问
        public Point 放大镜位置 => this.Location;
        public Size 放大镜尺寸 => this.Size;
        public Rectangle 放大镜区域 => new Rectangle(this.Location, this.Size);
        // 获取包含坐标信息的完整区域
        public Rectangle 完整区域 => new Rectangle(this.Location, new Size(this.Width, this.Height + 坐标信息高度));

        public 放大镜(int 窗口尺寸, int 采样区域尺寸)
        {
            放大倍数 = (int)(窗口尺寸 / 采样区域尺寸 * 0.7);
            采样尺寸 = 采样区域尺寸;

            InitializeComponent(窗口尺寸);
            显示放大镜();
        }

        private void InitializeComponent(int 尺寸)
        {
            this.SuspendLayout();

            // 窗体设置 - 高度增加坐标信息区域
            this.FormBorderStyle = FormBorderStyle.None;
            this.ShowInTaskbar = false;
            this.TopMost = true;
            this.Size = new Size(尺寸, 尺寸 + 坐标信息高度); // 增加高度容纳坐标信息
            this.BackColor = Color.Black;
            this.Padding = new Padding(1);

            // 设置窗体为鼠标穿透
            this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

            // 放大画面
            放大画面 = new PictureBox();
            放大画面.Size = new Size(尺寸 - 2, 尺寸 - 2);
            放大画面.Location = new Point(1, 1);
            放大画面.SizeMode = PictureBoxSizeMode.StretchImage;
            this.Controls.Add(放大画面);

            // 绘制边框和坐标信息区域
            this.Paint += (s, e) =>
            {
                e.Graphics.DrawRectangle(new Pen(Color.White, 2),
                    new Rectangle(0, 0, this.Width - 1, this.Height - 1));

                // 绘制放大镜和坐标信息的分隔线
                e.Graphics.DrawLine(new Pen(Color.White, 1),
                    0, 尺寸, this.Width, 尺寸);
            };

            this.ResumeLayout(false);
        }
        private void 显示放大镜()
        {
            // 设置窗体为工具窗口
            SetWindowLong(this.Handle, -20,
                GetWindowLong(this.Handle, -20) | 0x80);

            // 关键修改：设置窗体为鼠标穿透
            设置鼠标穿透(true);

            this.Show();
        }

        // 关键新增方法：设置鼠标穿透
        private void 设置鼠标穿透(bool 穿透)
        {
            if (穿透)
            {
                // 设置窗体为分层窗口并设置透明颜色
                SetWindowLong(this.Handle, GWL_EXSTYLE,
                    GetWindowLong(this.Handle, GWL_EXSTYLE) | WS_EX_LAYERED | WS_EX_TRANSPARENT);

                // 设置黑色为透明色（因为放大镜背景是黑色的）
                SetLayeredWindowAttributes(this.Handle, 0, 255, LWA_COLORKEY);
            }
            else
            {
                SetWindowLong(this.Handle, GWL_EXSTYLE,
                    GetWindowLong(this.Handle, GWL_EXSTYLE) & ~WS_EX_TRANSPARENT);
            }
        }

        // 或者使用更简单的方法：重写WndProc让鼠标事件穿透
        protected override void WndProc(ref Message m)
        {
            const int WM_NCHITTEST = 0x0084;
            const int HTTRANSPARENT = -1;

            if (m.Msg == WM_NCHITTEST)
            {
                m.Result = (IntPtr)HTTRANSPARENT;
                return;
            }

            base.WndProc(ref m);
        }

        [DllImport("user32.dll")]
        private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        [DllImport("user32.dll")]
        private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll")]
        private static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);

        private const int GWL_EXSTYLE = -20;
        private const int WS_EX_LAYERED = 0x80000;
        private const int WS_EX_TRANSPARENT = 0x20;
        private const int LWA_COLORKEY = 0x1;

        public void 更新位置(Point 鼠标位置, Bitmap 全屏图像)
        {
            if (this.IsDisposed) return;

            // 计算包含坐标信息的实际高度
            int 实际高度 = this.Height;

            // 默认放在鼠标右下方
            int x = 鼠标位置.X + 25;
            int y = 鼠标位置.Y + 25;

            // 调整位置确保完整区域在屏幕内
            if (x + this.Width > 屏幕宽度)
            {
                x = 鼠标位置.X - this.Width - 25;
            }
            if (y + 实际高度 > 屏幕高度)
            {
                y = 鼠标位置.Y - 实际高度 - 25;
            }
            if (x < 0)
            {
                x = 鼠标位置.X + 25;
                y = 鼠标位置.Y - 实际高度 - 25;
            }
            if (y < 0)
            {
                y = 鼠标位置.Y + 25;
                x = 鼠标位置.X - this.Width - 25;
            }

            // 确保在屏幕范围内
            x = Math.Max(0, Math.Min(x, 屏幕宽度 - this.Width));
            y = Math.Max(0, Math.Min(y, 屏幕高度 - 实际高度));

            this.Location = new Point(x, y);

            // 更新放大内容
            更新放大内容(鼠标位置, 全屏图像);
        }
        private void 更新放大内容(Point 鼠标位置, Bitmap 全屏图像)
        {
            try
            {
                int 半尺寸 = 采样尺寸 / 2;

                // 计算理想的采样中心点
                int 理想中心X = 鼠标位置.X;
                int 理想中心Y = 鼠标位置.Y;

                // 计算实际可用的采样区域（考虑屏幕边界）
                int 实际采样X = Math.Max(半尺寸, Math.Min(理想中心X, 全屏图像.Width - 半尺寸 - 1));
                int 实际采样Y = Math.Max(半尺寸, Math.Min(理想中心Y, 全屏图像.Height - 半尺寸 - 1));

                // 计算偏移量（实际采样中心与理想中心的差值）
                int 偏移X = 实际采样X - 理想中心X;  // 当鼠标在左边缘时，这个值是正的
                int 偏移Y = 实际采样Y - 理想中心Y;  // 当鼠标在上边缘时，这个值是正的

                // 计算采样区域（以实际采样中心为准）
                var 采样区域 = new Rectangle(
                    实际采样X - 半尺寸,
                    实际采样Y - 半尺寸,
                    采样尺寸,
                    采样尺寸
                );

                // 确保采样区域在图像范围内
                采样区域.X = Math.Max(0, 采样区域.X);
                采样区域.Y = Math.Max(0, 采样区域.Y);
                采样区域.Width = Math.Min(采样尺寸, 全屏图像.Width - 采样区域.X);
                采样区域.Height = Math.Min(采样尺寸, 全屏图像.Height - 采样区域.Y);

                if (采样区域.Width > 0 && 采样区域.Height > 0)
                {
                    // 采样并放大
                    using (var 采样图 = new Bitmap(采样区域.Width, 采样区域.Height))
                    using (var g = Graphics.FromImage(采样图))
                    {
                        g.DrawImage(全屏图像, new Rectangle(0, 0, 采样区域.Width, 采样区域.Height),
                                  采样区域, GraphicsUnit.Pixel);

                        // 创建放大后的图像
                        var 放大图 = new Bitmap(this.放大画面.Width, this.放大画面.Height);
                        using (var g2 = Graphics.FromImage(放大图))
                        {
                            g2.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
                            g2.DrawImage(采样图, new Rectangle(0, 0, 放大图.Width, 放大图.Height));

                            // 计算十字线偏移位置 - 修正：偏移方向应该相反
                            int 十字线偏移X = -偏移X * 放大倍数;  // 加上负号，方向相反
                            int 十字线偏移Y = -偏移Y * 放大倍数;  // 加上负号，方向相反

                            // 计算实际十字线中心位置
                            int 实际中心X = 放大图.Width / 2 + 十字线偏移X;
                            int 实际中心Y = 放大图.Height / 2 + 十字线偏移Y;

                            // 确保十字线在图像范围内
                            实际中心X = Math.Max(5, Math.Min(实际中心X, 放大图.Width - 6));
                            实际中心Y = Math.Max(5, Math.Min(实际中心Y, 放大图.Height - 6));

                            // 绘制偏移后的中心十字线
                            using (var 画笔 = new Pen(Color.Red, 1))
                            {
                                g2.DrawLine(画笔, 实际中心X - 5, 实际中心Y, 实际中心X + 5, 实际中心Y);
                                g2.DrawLine(画笔, 实际中心X, 实际中心Y - 5, 实际中心X, 实际中心Y + 5);
                            }
                        }

                        // 更新显示
                        if (this.放大画面.Image != null)
                            this.放大画面.Image.Dispose();

                        this.放大画面.Image = 放大图;
                    }
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"放大镜更新异常: {ex.Message}");
            }
        }
    }

    // 输入对话框
    public class 输入对话框 : Form
    {
        public string 答案 { get; private set; }
        private TextBox 输入框;

        public 输入对话框(string 提示, string 默认值 = "")
        {
            InitializeComponent(提示, 默认值);
        }

        private void InitializeComponent(string 提示, string 默认值)
        {
            this.SuspendLayout();

            this.Text = "输入";
            this.Width = 300;
            this.Height = 150;
            this.StartPosition = FormStartPosition.CenterScreen;
            this.FormBorderStyle = FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.TopMost = true;

            // 提示标签
            var 标签 = new Label
            {
                Text = 提示,
                Location = new Point(10, 10),
                Width = 280,
                AutoSize = true
            };

            // 输入框
            输入框 = new TextBox
            {
                Text = 默认值,
                Location = new Point(10, 40),
                Width = 260
            };

            // 按钮
            var 确定按钮 = new Button
            {
                Text = "确定",
                DialogResult = DialogResult.OK,
                Location = new Point(100, 70),
                Width = 80
            };

            var 取消按钮 = new Button
            {
                Text = "取消",
                DialogResult = DialogResult.Cancel,
                Location = new Point(190, 70),
                Width = 80
            };

            this.AcceptButton = 确定按钮;
            this.CancelButton = 取消按钮;

            确定按钮.Click += (s, e) =>
            {
                答案 = 输入框.Text;
                this.DialogResult = DialogResult.OK;
                this.Close();
            };

            this.Controls.AddRange(new Control[] { 标签, 输入框, 确定按钮, 取消按钮 });
            this.ResumeLayout(false);

            // 确保输入框获得焦点
            this.Shown += (s, e) => 输入框.Focus();
        }

    }
}
